﻿using System;
using System.Threading.Tasks;

namespace ESRI.ArcGIS.Client.Async
{
    public static partial class LayerExtensions
    {
        private static readonly Task CompletedTask;
        static LayerExtensions()
        {
            var tcs = new TaskCompletionSource<object>();
            tcs.SetResult(null);
            CompletedTask = tcs.Task;
        }

        /// <summary>
        /// Initializes the resource. Throws an exception on initialization failure.
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public static Task InitializeTaskAsync(this Layer layer)
        {
            if (layer == null) throw new ArgumentNullException("layer");
            var tcs = new TaskCompletionSource<object>();

            if (layer.IsInitialized)
            {
                if (layer.InitializationFailure == null)
                    return CompletedTask;
                
                var failureTcs = new TaskCompletionSource<object>();
                failureTcs.SetException(layer.InitializationFailure);
                return failureTcs.Task;
            }

            EventHandler<EventArgs> onCompleted = null;
            EventHandler<EventArgs> onFailed = null;
            onCompleted = (sender, args) =>
            {
                var senderLayer = (Layer)sender;

                // see Layer.InitializationFailed event description in the API reference
                // http://resources.arcgis.com/en/help/silverlight-api/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.Layer~InitializationFailed_EV.html
                if (senderLayer.InitializationFailure != null)
                    return;
                senderLayer.Initialized -= onCompleted;
                senderLayer.InitializationFailed -= onFailed;
                tcs.SetResult(null);
            };
            onFailed = (sender, args) =>
            {
                var senderLayer = (Layer)sender;
                senderLayer.Initialized -= onCompleted;
                senderLayer.InitializationFailed -= onFailed;
                tcs.SetException(senderLayer.InitializationFailure);
            };
            layer.Initialized += onCompleted;
            layer.InitializationFailed += onFailed;
            layer.Initialize();

            return tcs.Task;
        }
    }
}